package com.shenma2009.recv;

import com.alibaba.fastjson2.JSON;
import com.rabbitmq.client.Channel;
import com.shenma2009.service.TbOrderService;
import com.shenma2009.vo.KillVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author 军哥
 * @version 1.0
 * @description: SecKillMessageRecv
 * @date 2023/5/4 16:47
 */

@Component
@Slf4j
public class SecKillMessageRecv {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    TbOrderService tbOrderService;

    @RabbitListener(queues = "secKillQueue")
    public void onSecKillMessage(Message message, Channel channel) throws IOException {
        // 得到消息体
        String msg = new String(message.getBody());

        // 把消息转换为对象
        KillVo killVo = JSON.parseObject(msg, KillVo.class);

        // 判断重复抢的问题
        String bigKey = "SEC_KILL_RESULT_" + killVo.getKillId();
        Object o = redisTemplate.opsForHash().get(bigKey, "" + killVo.getUserId());
        if(o != null) {
            log.error("不允许重复抢,user={}", killVo.getUserId());
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }

        // 从redis中获取产品
        String key = "KILL_" + killVo.getKillId();
        // 在这里实现超抢的处理：decrement
        Long leftCount = redisTemplate.opsForValue().decrement(key);
        if(leftCount < 0) {
            // 已经抢光了
            redisTemplate.opsForHash().put(bigKey, ""+killVo.getUserId(), Integer.valueOf(2));

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
        else {
            redisTemplate.opsForHash().put(bigKey, ""+killVo.getUserId(), Integer.valueOf(1));
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

            // 生成订单
            Boolean ok = tbOrderService.addSecKillOrder(killVo.getUserId(), killVo.getKillId());
            if(ok) {
                log.info("订单成功");
            }
            else {
                log.error("订单失败");
            }
        }

    }

}
